package com.szwistar.common.comm.jsonrpc;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.szwistar.common.datastruct.JsonMapper;
import com.szwistar.common.datastruct.JsonObject;
import com.szwistar.common.datastruct.Utils;
import com.szwistar.common.os.DateTime;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 带有授权信息的 JSON-RPC 请求
 */
public abstract class JsonRpcMessageAuthorizedRequest extends JsonRpcMessageRequest {
	// 密钥
	protected String token;
	// 要调用的方法
	protected String method;
	// 调用 JSON 参数，接收者应根据 method 来判断此字段中 JSON 对象类型，并进行解析
	protected String params;
	protected Map<String, Object> paramMap;

	protected JsonRpcMessageAuthorizedRequest() {
		super();
	}

	protected JsonRpcMessageAuthorizedRequest(int msgType, String from, String token, String method, String params) {
		super(msgType, from);
		this.token  = token;
		this.method = method;
		this.params = params;
	}

	public String getToken() { return token; }
	public void setToken(String token) { this.token = token; }

	public String getMethod() {	return method; }
	public void setMethod(String method) { this.method = method; }

	public String getParams() { return params; }
	public void setParams(String params) { this.params = params; }

	public <T> T parseParam(Class<T> typeClazz) {
		try {
			return JsonMapper.fromJson(params, typeClazz);
		} catch (Exception e) {
			LOG.error("参数解码失败！{}", params, e);
			return null;
		}
	}

	@JsonIgnore
	public Map<String, Object> getParamMap() {
		if(paramMap != null) { return paramMap; }
		try {
			paramMap = JsonMapper.fromJson(params);
		} catch (Exception e) {
			LOG.error("参数解码失败！{}", e.getMessage());
		}

		if(paramMap == null) { paramMap = new JsonObject(); }
		return paramMap;
	}

    public Object[] getParaToArray(String key, Object[] defaultValue) {
        if (getParamMap().get(key) instanceof List) {
        	return ((List<?>)getParamMap().get(key)).toArray();
        }
        return defaultValue;
    }

    @SuppressWarnings("unchecked")
	public Map<String, Object> getParaToMap(String key, Map<String, Object> defaultValue) {
        if (getParamMap().get(key) instanceof Map) {
        	return (Map<String, Object>) getParamMap().get(key);
        }
        return defaultValue;
    }

    public String getParaToStr(String key, String defaultValue) {
        if (getParamMap().get(key) != null) {
        	return getParamMap().get(key).toString();
        }
        return defaultValue;
    }

    public Integer getParaToInt(String key, Integer defaultValue) {
        if (getParamMap().get(key) != null) {
        	if(getParamMap().get(key) instanceof String) {
        		return Integer.parseInt((String) getParamMap().get(key));
        	}
        	if(getParamMap().get(key) instanceof Long) {
        		return ((Long)getParamMap().get(key)).intValue();
        	}
            return (int) getParamMap().get(key);
        }
        return defaultValue;
    }

    public Long getParaToLong(String key, Long defaultValue) {
        if (getParamMap().get(key) != null) {
        	if(getParamMap().get(key) instanceof String) {
        		return Long.parseLong((String) getParamMap().get(key));
        	}
        	if(getParamMap().get(key) instanceof Integer) {
        		return ((Integer)getParamMap().get(key)).longValue();
        	}
            return (long) getParamMap().get(key);
        }
        return defaultValue;
    }

    public Float getParaToFloat(String key, Float defaultValue) {
        if (getParamMap().get(key) != null) {
        	if(getParamMap().get(key) instanceof String) {
        		return Float.parseFloat((String) getParamMap().get(key));
        	}
            return (float) getParamMap().get(key);
        }
        return defaultValue;
    }

    public Double getParaToDouble(String key, Double defaultValue) {
        if (getParamMap().get(key) != null) {
        	if(getParamMap().get(key) instanceof String) {
        		return Double.parseDouble((String) getParamMap().get(key));
        	}
            return (double) getParamMap().get(key);
        }
        return defaultValue;
    }

    public Boolean getParaToBool(String key, Boolean defaultValue) {
        if (getParamMap().get(key) != null) {
        	if(getParamMap().get(key) instanceof String) {
        		return ("on".equals(getParamMap().get(key)) || "true".equals(getParamMap().get(key)));
        	}
            return (boolean) getParamMap().get(key);
        }
        return defaultValue;
    }

    /**
     * 获取日期时间字段
     * 格式要求为 "YYYY-MM-DD HH:MM:SS"
     */
	public Date getParaToDate(String key, Date defaultValue) {
        if (getParamMap().get(key) != null) {
        	if(getParamMap().get(key) instanceof String) {
        		try {
					return DateTime.at((String) getParamMap().get(key));
				} catch (ParseException e) {
					return null;
				}
        	} else if(Utils.isAssignableFrom(Date.class, getParamMap().get(key).getClass())) {
        		return (Date) getParamMap().get(key);
        	}
        }
        return defaultValue;
    }
}
